package cn.com.libertymutual.sp.service.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;

import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.sp.req.RoleReq;
import cn.com.libertymutual.sp.service.api.RoleService;
import cn.com.libertymutual.sys.bean.SysMenu;
import cn.com.libertymutual.sys.bean.SysMenuRes;
import cn.com.libertymutual.sys.bean.SysRole;
import cn.com.libertymutual.sys.bean.SysRoleMenu;
import cn.com.libertymutual.sys.bean.SysRoleMenuRes;
import cn.com.libertymutual.sys.bean.SysRoleUser;
import cn.com.libertymutual.sys.dao.ISysMenuDao;
import cn.com.libertymutual.sys.dao.ISysMenuResDao;
import cn.com.libertymutual.sys.dao.ISysRoleDao;
import cn.com.libertymutual.sys.dao.ISysRoleMenuDao;
import cn.com.libertymutual.sys.dao.ISysRoleMenuResDao;
import cn.com.libertymutual.sys.dao.ISysRoleUserDao;
import cn.com.libertymutual.sys.service.api.SysMenuService;
@Service
public class RoleServiceImpl implements RoleService {
	private Logger log = LoggerFactory.getLogger(getClass());
	@Resource
	RedisUtils redisUtils;
	@Resource
	SysMenuService sysMenuService;
	@Autowired
	ISysRoleMenuResDao iSysRoleMenuResDao;
	@Autowired
	ISysMenuResDao menuResDao;
	@Autowired
	private ISysRoleDao iSysRoleDao;
	@Autowired
	private ISysMenuDao iSysMenuDao;
	@Autowired
	private ISysRoleUserDao iSysRoleUserDao;
	@Autowired
	private ISysRoleMenuDao iSysRoleMenuDao;
	@Override
	public ServiceResult roleList(String type,int pageNumber, int pageSize) {
		ServiceResult sr = new ServiceResult();
		Sort sort = new Sort(Direction.ASC, "roleid");
		Page<SysRole> page = iSysRoleDao.findAll(new Specification<SysRole>() {
			@Override
			public Predicate toPredicate(Root<SysRole> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

				List<Predicate> predicate = new ArrayList<Predicate>();
				if (StringUtils.isNotEmpty(type)) {
					if ("flowNode".equals(type)) {
						predicate.add(cb.equal(root.get("approveAuth").as(String.class), "1"));
					}
				}
				Predicate[] pre = new Predicate[predicate.size()];
				return query.where(predicate.toArray(pre)).getRestriction();
			}
		}, PageRequest.of(pageNumber - 1, pageSize, sort));
		sr.setResult(page);
		return sr;
	}
	@Override
	public ServiceResult addRoleMenu(String roleId, String[] menuIds) {
		ServiceResult sr = new ServiceResult();
		for (int i = 0; i < menuIds.length; i++) {
			SysRoleMenu srm = new SysRoleMenu();
			srm.setMenuid(Integer.parseInt(menuIds[i]));
			srm.setRoleid(roleId);
			iSysRoleMenuDao.save(srm);
		}
		sr.setSuccess();
		return sr;
	}
	@Override
	public ServiceResult menuList() {
		ServiceResult sr = new ServiceResult();
		Map<String, List<Integer>> menuMapRel = (Map<String, List<Integer>>) redisUtils
				.get(Constants.MENU_REL_INFO_KEY);
		log.info("menuMapRel===>:" + menuMapRel.toString());
		List<Integer> msd = menuMapRel.get("0");
		log.info(msd.toString());
		List<SysMenu> list = iSysMenuDao.findByMenuIds(msd);
		List<SysMenu> menuRecursiveList = menuRecursive(list);
		sr.setResult(menuRecursiveList);
		return sr;
	}
	public List<SysMenu> menuRecursive(List<SysMenu> list) {
		for (SysMenu ss : list) {// 1
			List<SysMenu> tmenu = iSysMenuDao.findByFmenuid(ss.getMenuid());
			if (null != tmenu && tmenu.size() != 0) {
				for (SysMenu qq : tmenu) {
					List<SysMenuRes> fmenu = menuResDao.findByMenuid(qq.getMenuid());
					if (null != fmenu && fmenu.size() != 0) {
						qq.setSmenu(fmenu);
					}
					// List<SysMenu> nmenu =
					// iSysMenuDao.findByFmenuid(qq.getMenuid());
					// if (null != nmenu && nmenu.size() != 0) {
					// qq.setStepMenu(nmenu);
					// }
				}
				ss.setSmenu(tmenu);
				menuRecursive(tmenu);
				// }else{
				// List<SysMenuRes> fmenu =
				// menuResDao.findByMenuid(ss.getMenuid());
				// if (null != fmenu && fmenu.size() != 0) {
				// ss.setSmenu(fmenu);
				// }
			}
		}
		return list;
	}
	// public List<SysMenu> roleMenuRecursive(String roleId,List<SysMenu> list)
	// {
	//
	// for (SysMenu ss : list) {
	// SysRoleMenu srm =
	// iSysRoleMenuDao.findByRoleAndMenuId(roleId,ss.getMenuid());
	// if (null != srm) {
	// ss.setIsleaf("true");
	// }else{
	// ss.setIsleaf("false");
	// }
	//
	// List<SysMenu> tmenu = iSysMenuDao.findByFmenuid(ss.getMenuid());
	// if (null != tmenu && tmenu.size() != 0) {
	// for (SysMenu qq : tmenu) {
	// SysRoleMenu tsrm =
	// iSysRoleMenuDao.findByRoleAndMenuId(roleId,qq.getMenuid());
	// if (null != tsrm) {
	// qq.setIsleaf("true");
	// }else{
	// qq.setIsleaf("false");
	// }
	// List<SysMenuRes> fmenu = menuResDao.findByMenuid(qq.getMenuid());
	// if (null != fmenu && fmenu.size() != 0) {
	// for (SysMenuRes fm:fmenu) {
	// SysRoleMenuRes srmr =
	// roleMenuResDao.findByRoleMenuRes(roleId,fm.getMenuid(),fm.getResid());
	// if (null != srmr) {
	// fm.setIsleaf("true");
	// }else{
	// fm.setIsleaf("false");
	// }
	// }
	// qq.setSmenu(fmenu);
	// }
	// }
	// ss.setSmenu(tmenu);
	// menuRecursive(tmenu);
	// }
	// }
	// return list;
	// }
	public List<SysMenu> roleMenuRecursive(List<SysMenu> list, List<Integer> roleMenuIds, String roleId) {
		for (SysMenu tt : list) {
			log.info("Menuid()-----------" + String.valueOf(tt.getMenuid()) + "======Fmenuid======="
					+ String.valueOf(tt.getFmenuid()));
			log.info("contains-----------" + String.valueOf(roleMenuIds.contains(tt.getMenuid())));
			List<SysMenu> thList = iSysMenuDao.findByFmenuid(tt.getMenuid());// 165,166,167
			List<SysMenu> newList = Lists.newArrayList();
			for (SysMenu qq : thList) {
				if (roleMenuIds.contains(qq.getMenuid())) {
					List<SysRoleMenuRes> fmenu = iSysRoleMenuResDao.findByRoleidAndMenuid(roleId, qq.getMenuid());
					if (null != fmenu && fmenu.size() != 0) {
						log.info("--" + qq.getMenuid() + "---add->" + fmenu.toString());
						qq.setSmenu(fmenu);
						log.info("qq--" + qq.getMenuid() + "--" + qq.getSmenu().toString());
					}
					newList.add(qq);
				}
				tt.setSmenu(newList);
				roleMenuRecursive(newList, roleMenuIds, roleId);
			}
		}
		return list;
	}
	@Override
	public ServiceResult roleMenuList(String roleId) {
		ServiceResult sr = new ServiceResult();
		List<Integer> roleMenuIds = iSysRoleMenuDao.findMenuIdList(roleId);// 角色对应的所有的菜单id
		Map<String, List<Integer>> menuMapRel = (Map<String, List<Integer>>) redisUtils
				.get(Constants.MENU_REL_INFO_KEY);
		List<Integer> msd = menuMapRel.get("0"); // 所有一级菜单的menuId
		
		if( msd != null )
			msd.retainAll(roleMenuIds);
		
		if (null != msd && msd.size() != 0) {
			List<SysMenu> fmenu = iSysMenuDao.findByMenuIds(msd);
			log.info(msd.toString());
			List<SysMenu> returnback = roleMenuRecursive(fmenu, roleMenuIds, roleId);
			// List<Integer> msd = menuMapRel.get("1");
			// log.info(msd.toString());
			// List<SysMenu> list = iSysMenuDao.findByMenuIds(msd);
			// List<SysMenu> returnback = roleMenuRecursive(roleId,list);
			log.info(returnback.toString());
			sr.setResult(returnback);
		}
		return sr;
	}
	
	@Transactional
	@Override
	public ServiceResult updateStatus(String type, Integer roleId) {
		ServiceResult sr = new ServiceResult();
		if (type.equals("0")) {
			List<SysRoleUser> sru = iSysRoleUserDao.findByRoleid(roleId);
			if (null != sru && sru.size() != 0) {
				sr.setResult("请先删除拥有该角色的用户！");
				sr.setFail();
			} else {
				iSysRoleDao.updateStatus(type, roleId);
				iSysRoleMenuDao.deleteByRoleId(String.valueOf(roleId));
				iSysRoleMenuResDao.deleteByRoleId(String.valueOf(roleId));
				sr.setSuccess();
			}
		} else {
			iSysRoleDao.updateStatus(type, roleId);
			iSysRoleMenuDao.deleteByRoleId(String.valueOf(roleId));
			iSysRoleMenuResDao.deleteByRoleId(String.valueOf(roleId));
			sr.setSuccess();
		}
		return sr;
	}
//  原始	
//	@Transactional
//	@Override
//	public ServiceResult setPermission(RoleReq roleReq) {
//		ServiceResult sr = new ServiceResult();
//		String roleId = roleReq.getRoleId();
//		log.info("roleId--------" + roleReq.getRoleId());
//		iSysRoleMenuResDao.deleteByRoleId(roleId);
//		iSysRoleMenuDao.deleteByRoleId(roleId);
//		SysRole srole = iSysRoleDao.findByRoleid(Integer.parseInt(roleId));
//		if (null != srole) {
//			srole.setRemarks(roleReq.getRemark());
//			srole.setRolename(roleReq.getRoleName());
//			srole.setStatus("1");
//			iSysRoleDao.save(srole);
//		}
//		SysRoleMenu ss = new SysRoleMenu();
//		if (null != roleReq.getFmenuIds() && roleReq.getFmenuIds().size() != 0) {
//			log.info("-----getFmenuIds---->:" + roleReq.getFmenuIds().toString());
//			for (Integer fmenu : roleReq.getFmenuIds()) {
//				SysRoleMenu dbfmenu = iSysRoleMenuDao.findByRoleAndMenuId(roleId, fmenu);
//				if (null == dbfmenu) {
//					ss.setMenuid(fmenu);
//					ss.setRoleid(roleId);
//					iSysRoleMenuDao.save(ss);
//				} else {
//					continue;
//				}
//			}
//		}
//		if ((null != roleReq.getFmenuIds() && roleReq.getFmenuIds().size() != 0)
//				|| (null != roleReq.getResids() && roleReq.getResids().size() != 0)) {
//			ss.setMenuid(1);
//			ss.setRoleid(roleId);
//			iSysRoleMenuDao.save(ss);
//		}
//		SysRoleMenuRes srmr = new SysRoleMenuRes();
//		HashSet<Integer> fmenuIds = new HashSet<Integer>();
//		if (null != roleReq.getResids() && roleReq.getResids().size() != 0) {
//			log.info("-----getResids---->:" + roleReq.getResids().toString());
//			for (String i : roleReq.getResids()) {
//				SysMenuRes smr = menuResDao.findByResid(i);
//				if (null!=smr) {
//					fmenuIds.add(smr.getMenuid());
//					srmr.setMenuid(smr.getMenuid());
//					srmr.setResid(i);
//					srmr.setRoleid(roleId);
//					iSysRoleMenuResDao.save(srmr);
//				}
//			}
//		}
//		log.info("-----set集合--->:" + fmenuIds.toString());
//		setRoleMenu(fmenuIds, roleId);
//		sr.setSuccess();
//		return sr;
//	}
//	
//	private void setRoleMenu(HashSet<Integer> menuIds, String roleId) {
//		HashSet<Integer> fmenuIds = new HashSet<Integer>();
//		SysRoleMenu ss = new SysRoleMenu();
//		for (Integer menuId : menuIds) {
//			SysMenu smList = iSysMenuDao.findByMenuId(menuId);
//			fmenuIds.add(smList.getFmenuid());
//			SysRoleMenu dbsrm = iSysRoleMenuDao.findByRoleAndMenuId(roleId, menuId);
//			if (null == dbsrm) {
//				ss.setMenuid(menuId);
//				ss.setRoleid(roleId);
//				iSysRoleMenuDao.save(ss);
//			} else {
//				continue;
//			}
//			setRoleMenu(fmenuIds, roleId);
//		}
//	}
	
	
	
	@Transactional
	@Override
	public ServiceResult setPermission(RoleReq roleReq) {
		ServiceResult sr = new ServiceResult();
		String roleId = roleReq.getRoleId();
		log.info("roleId--------" + roleReq.getRoleId());
		iSysRoleMenuResDao.deleteByRoleId(roleId);
		iSysRoleMenuDao.deleteByRoleId(roleId);
		SysRole srole = iSysRoleDao.findByRoleid(Integer.parseInt(roleId));
		if (null != srole) {
			srole.setRemarks(roleReq.getRemark());
			srole.setRolename(roleReq.getRoleName());
			srole.setApproveAuth(roleReq.getApproveAuth());
			srole.setConfigAuth(roleReq.getConfigAuth());
			srole.setStatus("1");
			iSysRoleDao.save(srole);
		}
		SysRoleMenuRes srmr = new SysRoleMenuRes();
		SysRoleMenu srm = new SysRoleMenu();
		HashSet<Integer> fmenuIds = new HashSet<Integer>();
		if (CollectionUtils.isNotEmpty(roleReq.getResids())) {
			log.info("-----getResids---->:" + roleReq.getResids().toString());
			String reg = "^(\\-|\\+)?\\d+(\\.\\d+)?$";
			for (String res : roleReq.getResids()) {
				if (Pattern.compile(reg).matcher(res).find()) {//菜单
					log.info("数字--菜单--{}",res);
					SysRoleMenu roleM = iSysRoleMenuDao.findByRoleAndMenuId(roleId, Integer.parseInt(res));
					if (null==roleM) {
						fmenuIds.add(Integer.parseInt(res));
						srm.setMenuid(Integer.parseInt(res));
						srm.setRoleid(roleId);
						iSysRoleMenuDao.save(srm);
					}
				}else {//按钮
					log.info("字符串--按钮--{}",res);
					SysMenuRes smr = menuResDao.findByResid(res);
					if (null!=smr) {
						fmenuIds.add(smr.getMenuid());
						srmr.setMenuid(smr.getMenuid());
						srmr.setResid(res);
						srmr.setRoleid(roleId);
						iSysRoleMenuResDao.save(srmr);
					}
				}
			}
		}
		log.info("-----set集合--->:" + fmenuIds.toString());
		setRoleMenu(fmenuIds, roleId);
		sr.setSuccess();
		return sr;
	}
	
	private void setRoleMenu(HashSet<Integer> menuIds, String roleId) {
		log.info("-----menuIds集合--->:" + menuIds.toString());
		SysRoleMenu ss = new SysRoleMenu();
		for (Integer menuId : menuIds) {
			HashSet<Integer> fmenuIds = new HashSet<Integer>();
			log.info("-------menuId------------{}",menuId);
			SysMenu smList = iSysMenuDao.findByMenuId(menuId);
			if (null!=smList) {
				log.info("-------add fmenuId------------{}",smList.getFmenuid());
				fmenuIds.add(smList.getFmenuid());
			}
			SysRoleMenu dbsrm = iSysRoleMenuDao.findByRoleAndMenuId(roleId, menuId);
			if (null == dbsrm) {
				ss.setMenuid(menuId);
				ss.setRoleid(roleId);
				iSysRoleMenuDao.save(ss);
			}
			setRoleMenu(fmenuIds, roleId);
		}
	}
	
	
	
	@Transactional
	@Override
	public ServiceResult addRole(RoleReq roleReq) {
		ServiceResult sr = new ServiceResult();
		SysRole srole = new SysRole();
		srole.setRemarks(roleReq.getRemark());
		srole.setRolename(roleReq.getRoleName());
		srole.setApproveAuth(roleReq.getApproveAuth());
		srole.setConfigAuth(roleReq.getConfigAuth());
		srole.setStatus("1");
		SysRole dbsrole = iSysRoleDao.save(srole);
		String roleId = String.valueOf(dbsrole.getRoleid());
		SysRoleMenu ss = new SysRoleMenu();
		if (null != roleReq.getFmenuIds() && roleReq.getFmenuIds().size() != 0) {
			log.info("-----getFmenuIds---->:" + roleReq.getFmenuIds().toString());
			for (Integer fmenu : roleReq.getFmenuIds()) {
				ss.setMenuid(fmenu);
				ss.setRoleid(roleId);
				iSysRoleMenuDao.save(ss);
			}
		}
		ss.setMenuid(1);
		ss.setRoleid(roleId);
		iSysRoleMenuDao.save(ss);
		SysRoleMenuRes srmr = new SysRoleMenuRes();
		if (null != roleReq.getResids() && roleReq.getResids().size() != 0) {
			log.info("-----getResids---->:" + roleReq.getResids().toString());
			HashSet<Integer> fmenuIds = new HashSet<Integer>();
			for (String i : roleReq.getResids()) {
				SysMenuRes smr = menuResDao.findByResid(i);
				fmenuIds.add(smr.getMenuid());
				srmr.setMenuid(smr.getMenuid());
				srmr.setResid(i);
				srmr.setRoleid(roleId);
				iSysRoleMenuResDao.save(srmr);
			}
			log.info("fmenuIds set--->:" + fmenuIds.toString());
			setRoleMenu(fmenuIds, roleId);
		}
		sr.setSuccess();
		return sr;
	}
}